#include "stdafx.h"
#include "MainWindow.h"
#include "ui_MainWindow.h"
#include "moc_MainWindow.cpp"
#include <QtWidgets/QFileDialog>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QShortcut>
#include "AboutBox.h"

#pragma region Constructor

#define CONNECT_TEXTFIELD(field, property) 	connect(ui->field, &QLineEdit::textEdited, &_vm, &CharacterVM::set##property ); \
	connect(&_vm, &CharacterVM::##property##Changed, ui->field, &QLineEdit::setText );

#define CONNECT_INTSPIN(field, property) 	connect(ui->field, (void (QSpinBox::*)(int))&QSpinBox::valueChanged, &_vm, &CharacterVM::set##property ); \
	connect(&_vm,&CharacterVM::##property##Changed, ui->field, &QSpinBox::setValue );

#define CONNECT_TEXTEDIT(field, property) 	connect(ui->field, &QTextEdit::textChanged, this, &MainWindow::set##property ); \
	connect(&_vm, &CharacterVM::##property##Changed, ui->field, &QTextEdit::setHtml );

MainWindow::MainWindow(QWidget * parent) :
	ui(new Ui::MainWindow)
{
	ui->setupUi(this);

	connect(ui->actionNew, &QAction::triggered, this, &MainWindow::OnNew);
	connect(ui->actionSave_As, &QAction::triggered, this, &MainWindow::OnSaveAs);
	connect(ui->actionSave, &QAction::triggered, this, &MainWindow::OnSave);
	connect(ui->actionOpen, &QAction::triggered, this, &MainWindow::OnLoad);
	connect(ui->actionAbout, &QAction::triggered, this, &MainWindow::OnAbout);
	connect(ui->setImageButton, &QPushButton::clicked, this, &MainWindow::OnSetImage);

	// Main Window Title
	connect(ui->nameField, &QLineEdit::textChanged, this, &MainWindow::setWindowName );

	// Property connections
	CONNECT_TEXTFIELD(nameField, Name);
	CONNECT_TEXTFIELD(alignmentField, Alignment);
	CONNECT_TEXTFIELD(occupationField, Occupation);
	CONNECT_TEXTFIELD(typeField, Type);
	CONNECT_INTSPIN(iqField, IQ);
	CONNECT_INTSPIN(meField, ME);
	CONNECT_INTSPIN(maField, MA);
	CONNECT_INTSPIN(psField, PS);
	CONNECT_INTSPIN(ppField, PP);
	CONNECT_INTSPIN(peField, PE);
	CONNECT_INTSPIN(pbField, PB);
	CONNECT_INTSPIN(spdField, SPD);
	CONNECT_INTSPIN(hpField, HP);
	CONNECT_INTSPIN(sdcField, SDC);

	// Image connection
	connect(&_vm, &CharacterVM::ImageChanged, ui->imageLabel, &QLabel::setPixmap );

	// Skills page
	ui->primarySkills->setModel(&_vm.PrimarySkills());
    _primSkillDelete = new QShortcut(QKeySequence(QKeySequence::Delete), ui->primarySkills);
    connect(_primSkillDelete, &QShortcut::activatedAmbiguously, this, &MainWindow::primSkillDelete);
	ui->secondarySkills->setModel(&_vm.SecondarySkills());
    _secSkillDelete = new QShortcut(QKeySequence(QKeySequence::Delete), ui->secondarySkills);
    connect(_secSkillDelete, &QShortcut::activatedAmbiguously, this, &MainWindow::secSkillDelete);

	// Extraordinary Abilities page
	ui->extraordinaryAbilities->setModel(&_vm.ExtraordinaryAbilities());
    _eaDelete = new QShortcut(QKeySequence(QKeySequence::Delete), ui->extraordinaryAbilities);
    connect(_eaDelete, &QShortcut::activated, this, &MainWindow::eaDelete);

	// Combat page
	connect(&_vm, &CharacterVM::HPChanged, this, &MainWindow::HPChanged );
	connect(&_vm, &CharacterVM::SDCChanged, this, &MainWindow::SDCChanged );
	CONNECT_TEXTFIELD(handtohandField, HandToHandType);
	CONNECT_INTSPIN(numAttacksField, NumAttacks);
	CONNECT_INTSPIN(strikeField, Strike);
	CONNECT_INTSPIN(damageField, Damage);
	CONNECT_INTSPIN(kickField, Kick);
	CONNECT_INTSPIN(parryField, Parry);
	CONNECT_INTSPIN(rollField, Roll);
	CONNECT_INTSPIN(dodgeField, Dodge);
	CONNECT_INTSPIN(criticalField, Critical);
	CONNECT_INTSPIN(hpCurField, CurrentHP);
	CONNECT_INTSPIN(sdcCurField, CurrentSDC);
	CONNECT_TEXTEDIT(specialField, Special);
	CONNECT_TEXTEDIT(saveField, SaveBonus);
	CONNECT_TEXTEDIT(notesField, Notes);
	ui->weaponProficiencies->setModel(&_vm.WeaponProficiencies());
    _wpDelete = new QShortcut(QKeySequence(QKeySequence::Delete), ui->weaponProficiencies);
    connect(_wpDelete, &QShortcut::activated, this, &MainWindow::wpDelete);
     
	//Equipment Page
	ui->equipmentList->setModel(&_vm.Equipment());
    _equipmentDelete = new QShortcut(QKeySequence(QKeySequence::Delete), ui->equipmentList);
    connect(_equipmentDelete, &QShortcut::activated, this, &MainWindow::equipmentDelete);
}


MainWindow::~MainWindow(void)
{
}

#pragma endregion

#pragma region Signals and Slots

void MainWindow::primSkillDelete()
{
	tableDelete(ui->primarySkills);
}

void MainWindow::secSkillDelete()
{
	tableDelete(ui->secondarySkills);
}

void MainWindow::equipmentDelete()
{
	tableDelete(ui->equipmentList);
}

void MainWindow::wpDelete()
{
	tableDelete(ui->weaponProficiencies);
}

void MainWindow::eaDelete()
{
	tableDelete(ui->extraordinaryAbilities);
}

void MainWindow::tableDelete(QTableView * table)
{
	QModelIndex idx = table->currentIndex();
	if (idx.isValid() && idx.row() < (table->model()->rowCount() - 1))
		table->model()->removeRow(idx.row(), idx.parent());
}

void MainWindow::OnSave()
{
	if (_fileName.isEmpty())
	{
		OnSaveAs();
	}
	else
	{
		_vm.Serialize(_fileName);
	}
}

void MainWindow::OnNew()
{
	CharacterVM vmNew;
	ui->specialField->blockSignals(true);
	ui->saveField->blockSignals(true);
	ui->notesField->blockSignals(true);

	_vm.CopyDataFrom(vmNew);

	ui->specialField->blockSignals(false);
	ui->saveField->blockSignals(false);
	ui->notesField->blockSignals(false);
	_fileName = QString();
}

void MainWindow::OnSaveAs()
{
	 QString fileName = QFileDialog::getSaveFileName(this, tr("Save Character"), "", tr("Palladium Character File (*.pcf);;All Files (*)"));

	 _vm.Serialize(fileName);

	 _fileName = fileName;
}

void MainWindow::OnLoad()
{
	 QString fileName = QFileDialog::getOpenFileName(this, tr("Load Character"), "", tr("Palladium Character File (*.pcf);;All Files (*)"));

	 CharacterVM vmNew;

	 if (vmNew.Deserialize(fileName))
	 {
		 ui->specialField->blockSignals(true);
		 ui->saveField->blockSignals(true);
		 ui->notesField->blockSignals(true);

		 _vm.CopyDataFrom(vmNew);
		 _fileName = fileName;

		 ui->specialField->blockSignals(false);
		 ui->saveField->blockSignals(false);
		 ui->notesField->blockSignals(false);
	 }
}

void MainWindow::OnAbout()
{
	AboutBox dlg;

	dlg.exec();
}

void MainWindow::OnSetImage()
{
	 QString fileName = QFileDialog::getOpenFileName(this, tr("Load Character"), "", tr("Image Files (*.BMP *.GIF *.JPG *.JPEG *.PNG *.PBM *.PGM *.PPM *.XBM *.XPM);;All Files (*)"));

	 QFile file(fileName);

	 if (file.open(QIODevice::ReadOnly))
	 {
		_vm.setImage(file.readAll());	 
	 }
}

void MainWindow::HPChanged(int value)
{
	ui->hpMaxField->setText(QVariant(value).toString());
}

void MainWindow::SDCChanged(int value)
{
	ui->sdcMaxField->setText(QVariant(value).toString());
}

void MainWindow::setSaveBonus()
{
	_vm.blockSignals(true);
	_vm.setSaveBonus(ui->saveField->toHtml());
	_vm.blockSignals(false);
}

void MainWindow::setSpecial()
{
	_vm.blockSignals(true);
	_vm.setSpecial(ui->specialField->toHtml());
	_vm.blockSignals(false);
}

void MainWindow::setNotes()
{
	_vm.blockSignals(true);
	_vm.setNotes(ui->notesField->toHtml());
	_vm.blockSignals(false);
}

void MainWindow::setWindowName(QString value)
{
	if (value.isEmpty())
		setWindowTitle("Palladium Character Manager");
	else
		setWindowTitle("Palladium Character Manager - " + value);
}

#pragma endregion
